package cn.thoughtworks.school.pactise.diary.application.usecases.comment;

import cn.thoughtworks.school.pactise.diary.adapters.inbound.rest.resources.comment.CommentDto;
import cn.thoughtworks.school.pactise.diary.adapters.inbound.rest.resources.follow.PractiseWithCommentsDto;
import cn.thoughtworks.school.pactise.diary.adapters.inbound.rest.resources.practiseDiary.PractiseDiaryRequest;
import cn.thoughtworks.school.pactise.diary.application.gateway.user.UserDto;
import cn.thoughtworks.school.pactise.diary.application.gateway.user.UserService;
import cn.thoughtworks.school.pactise.diary.domain.context.practiseDiaryContext.comment.Comment;
import cn.thoughtworks.school.pactise.diary.domain.context.practiseDiaryContext.comment.CommentRepository;
import cn.thoughtworks.school.pactise.diary.domain.context.practiseDiaryContext.practiseDiary.PractiseDiary;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

@Service
public class QueryCommentUseCase {
    private final CommentRepository commentRepository;
    private final UserService userService;

    public QueryCommentUseCase(CommentRepository commentRepository, UserService userService) {
        this.commentRepository = commentRepository;
        this.userService = userService;
    }

    public List<Comment> findByPractiseDiaryId(Long id) {
        return commentRepository.findByPractiseDiaryId(id);
    }

    public List<PractiseWithCommentsDto> attachComments(List<PractiseDiary> practiseDiaries) {
        List<PractiseWithCommentsDto> practiseAndCommentMaps = new ArrayList();
        for (PractiseDiary practiseDiary : practiseDiaries) {
            List<Comment> comments = commentRepository.findByPractiseDiaryId(practiseDiary.getId());
            List<CommentDto> commentInfos = getCommonInfo(comments);
            practiseAndCommentMaps.add(new PractiseWithCommentsDto(PractiseDiaryRequest.of(practiseDiary), commentInfos));
        }

        return practiseAndCommentMaps;
    }

    public List<CommentDto> getCommonInfo(List<Comment> comments) {
        List<CommentDto> result = new ArrayList();
        List<Long> commentAuthorIds = comments.stream().map(Comment::getCommentAuthorId).collect(Collectors.toList());
        List<UserDto> users = userService.getUsersByIds(commentAuthorIds);
        comments.forEach(comment -> {
            UserDto commonUserInfo = users.stream().filter(item ->
                Objects.equals(item.getId(), comment.getCommentAuthorId()))
                .findFirst()
                .orElse(new UserDto());
            result.add(new CommentDto(commonUserInfo, comment));
        });

        return result;
    }
}
